package tankgame;

import sun.awt.image.ToolkitImage;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Vector;

/**
 * @author: lizhiwen
 * @version: 1.0
 */
public class MyPanel extends JPanel implements KeyListener,Runnable, MouseListener {
    MyTank myTank = null;
    //设置敌方坦克集合，保存数据集合
    Vector<EnemyTank> enemyTanks = new Vector<>();
    Vector<Node> nodes = new Vector<>();
    //设置墙集合
    Vector<WallNode> wallNodes = new Vector<>();
    //敌方坦克数量
    int enemyTankNum = 8;
    //设置爆炸集合
    Vector<Bomb> bombs = new Vector<>();
    //设置墙集合
    Vector<Wall> walls = new Vector<>();
    //初始化图片
    Image image1 = null;
    Image image2 = null;
    Image image3 = null;
    Image image4 = null;
    Image image5 = null;
    Image image6 = null;
    //定义一个等级变量
    private int level = 1;
    //定义以下强化变量
    private int tang = 0;
    private int xue = 0;
    private int shotSpeed = 1;
    private int tankSpeed = 1;
    private int shotSize = 1;
    private int shotNum = 1;
    private int experience = 0;
    //实现强化随机的变量
    int rand =  ((int)(Math.random() * 2));




    public MyPanel( String choice){
        //指向备份数据的文件
        File file = new File(Record.getRecordFile());
        try {
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            //该文件存在且不为空时将从中拷贝的数据取出，否则强制开新游戏
            if (file.exists() && (bufferedReader.readLine())!= null ){
                nodes = Record.getNodeAndScore();
                wallNodes = Record.getWallNodeAndScore();
            }else {
                choice = "1";
            }
            bufferedReader.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        //将目前的场上的敌方坦克信息传出并让其拷贝
        Record.setEnemyTanks(enemyTanks);




        switch (choice){
            case "1" :
                //初始化墙
                createWall();
                Record.setWalls(walls);

                //开新游戏，创建敌人坦克，这里同时创建子弹，并将敌方坦克添加到集合里
                for (int i = 0;i < enemyTankNum; i++){
                    EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 0);
                    enemyTank.setEnemyTanks(enemyTanks);
                    enemyTank.setWalls(walls);
                    enemyTank.setDirect(2);
                    new Thread(enemyTank).start();
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    enemyTank.shots.add(shot);
                    new Thread(shot).start();
                    enemyTanks.add(enemyTank);
                }
                //建立我方坦克
                myTank = new MyTank(350, 690);
                myTank.setWalls(walls);
                //设置我方坦克速度
                myTank.setSpeed(5 * tankSpeed);
                //将目前的场上的敌方坦克信息传出并让其拷贝
                Record.setMyTank(myTank);

                break;
            case "2" :
                //获得墙
                for (int i = 0;i < wallNodes.size(); i++){
                    WallNode wallNode = wallNodes.get(i);
                    Wall wall = new Wall(wallNode.getX(),wallNode.getY());
                    walls.add(wall);
                }
                Record.setWalls(walls);

                //继续游戏，创建敌人坦克，这里同时创建子弹，并将敌方坦克添加到集合里
                for (int i = 0;i < nodes.size(); i++){
                    Node node = nodes.get(i);
                    EnemyTank enemyTank = new EnemyTank(node.getX(),node.getY());
                    enemyTank.setWalls(walls);
                    enemyTank.setEnemyTanks(enemyTanks);
                    enemyTank.setDirect(node.getDirect());
                    new Thread(enemyTank).start();
                    Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
                    enemyTank.shots.add(shot);
                    new Thread(shot).start();
                    enemyTanks.add(enemyTank);

                }
                //建立我方坦克
                myTank = Record.getMyTank();
                myTank.setWalls(walls);
                //设置我方坦克速度
                myTank.setSpeed(20);
                //将目前的场上的敌方坦克信息传出并让其拷贝
                Record.setMyTank(myTank);
                break;
        }



        //播放音乐
        new MusicPlay("src\\Alarm10.wav").start();

        //初始化图片
        image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/1.png"));
        image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/2.png"));
        image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/3.png"));
        image4 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/唐小天.jpg"));
        image5 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/BrickWall.png"));
        image6 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/StoneWall.png"));
    }



    public void paint(Graphics g){
        super.paint(g);
        g.fillRect(0,0,1000,750);
        //画信息
        showInfo(g);
        //根据情况决定是否画强化信息
        if ((myTank.liveNum - 2 + shotSpeed - 1 + shotSize - 1 +
                shotNum - 1 + tankSpeed - 1 + tang + xue) != (level - 1)) {
            showStrongInfo(g);
        }


        //画我的坦克
        if (myTank != null && myTank.isLive && myTank.liveNum != 0) {
            drawTank(myTank.getX(), myTank.getY(), g, myTank.getDirect(), 0);
        }

        //画敌方坦克
        for (int i = 0 ; i < enemyTanks.size(); i++){
            EnemyTank enemyTank = enemyTanks.get(i);
            if (enemyTank.isLive) {
                drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);
                //画敌方子弹
                for (int j = 0; j < enemyTank.shots.size(); j++) {
                    Shot shot = enemyTank.shots.get(j);
                    if (shot.isLive) {
                        g.draw3DRect(shot.x, shot.y, 1, 1, false);
                    } else {
                        enemyTank.shots.remove(shot);
                    }
                }
            }
        }


        //画我方坦克子弹
        for (int i = 0; i < myTank.shots.size(); i++) {
            Shot shot = myTank.shots.get(i);
            if (shot != null && shot.isLive) {
                g.setColor(Color.cyan);
                if (shotSize == 1){
                    g.draw3DRect(shot.x, shot.y, 1, 1, false);
                }
                if (shotSize != 1) {
                    g.fillOval(shot.x - (10 * (shotSize - 1)), shot.y - (20 * (shotSize - 1)),
                            (shotSize - 1) * 20, (shotSize - 1) * 20);
                }
            } else {
                myTank.shots.remove(shot);
            }
        }



        //给图片加载的时间
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //画爆炸
        //第一次太快了，需要优化
        for (Bomb bomb : bombs){
            if (bomb.life > 6){
                g.drawImage(image1,bomb.x,bomb.y,60,60,this);
            }else if (bomb.life > 3) {
                g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);
            }else {
                g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);
            }
            bomb.lifeDown();
            if (bomb.life == 0){
                bombs.remove(bomb);
                //为啥要加break?
                break;
            }
        }


        //画墙
        for (int i = 0;i < walls.size();i++){
            Wall wall = walls.get(i);
            if (wall.isLive){
                if (wall.wallType == wall.ORDINARY_WALL){
                    g.drawImage(image5,wall.x,wall.y,20,20,this);
                }
                if (wall.wallType == wall.IRON_WALL){
                    g.drawImage(image6,wall.x,wall.y,20,20,this);
                }
            }
        }


        //画唐小天
        g.drawImage(image4,470,690,60,60,this);

    }


    //初始化墙
    public void createWall(){
        for (int i = 670; i <= 730;i += 20){
            Wall wall = new Wall(450,i);
            walls.add(wall);
        }
        for (int i = 470; i <= 530;i += 20){
            Wall wall = new Wall(i,670);
            walls.add(wall);
        }
        for (int i = 690; i <= 730;i += 20){
            Wall wall = new Wall(530,i);
            walls.add(wall);
        }
        for (int i = 650; i <= 730;i += 20){
            Wall wall = new Wall(430,i);
            walls.add(wall);
        }
        for (int i = 450; i <= 550;i += 20){
            Wall wall = new Wall(i,650);
            walls.add(wall);
        }
        for (int i = 670; i <= 730;i += 20){
            Wall wall = new Wall(550,i);
            walls.add(wall);
        }
        //以上为包围唐小天的
        //以下为中间部分
        for (int i = 0; i <= 980;i += 20){
            for (int j =  300;j <= 500;j += 20){
                Wall wall = new Wall(i,j);
                walls.add(wall);
            }
        }
    }

    //当选择唐小天后修改墙
    public void setWall(){
        for (Wall wall : walls){
            if (!(wall.y >= 300 && wall.y <= 500)){
                wall.wallType = 2;
            }
        }
    }

    //画成绩
    public void showInfo(Graphics g){
        g.setColor(Color.BLACK);
        Font font = new Font("宋体", Font.BOLD, 25);
        g.setFont(font);
        g.drawString("你累计击毁敌方坦克：",1020,30);
        drawTank(1020,60,g,0,1);
        g.setColor(Color.BLACK);
        g.drawString(Record.getHitTankNum() + "",1080,110);
        g.drawString("-------------------当前属性------------------",1020,480);
        g.drawString("当前等级: " + level + "" + "  升级所需经验值："
                + experience + "" + "/" + level + "",1020,510);
        g.drawString("当前生命值: " + myTank.liveNum + "" ,1020,540);
        g.drawString("子弹体积：" + shotSize + "",1020,570);
        g.drawString("子弹速度：" + shotSpeed + "",1020,600);
        g.drawString("子弹可连发数：" + shotNum + "",1020,630);
        g.drawString("坦克速度：" + tankSpeed + "",1020,660);
        if (tang == 1){
            g.drawString("顽强的唐小天",1020,690);
        }
        if (xue == 1 && tang != 1){
            g.drawString("薛定谔的子弹",1020,690);
        }
        if (xue == 1 && tang == 1){
            g.drawString("薛定谔的子弹",1020,720);
        }
    }


    //画强化信息
    public void showStrongInfo(Graphics g){
        //先画框
        g.draw3DRect(1020,250,200,200,true);
        g.draw3DRect(1240,250,200,200,true);
        g.draw3DRect(1460,250,200,200,true);
        g.drawString("------------------请选择强化---------------",1020,200);

        if (level == 2){
            g.drawString("顽强的唐小天" ,1040,280);
            g.drawString("保护唐小天的墙",1030,320);
            g.drawString("将会变为铁墙",1030,350);
            g.drawString("子弹速度提升" ,1260,330);
            g.drawString("子弹体积提升" ,1480,330);
        }
        if (level == 3){
            g.drawString("薛定谔的子弹" ,1040,280);
            g.drawString("敌方坦克的子弹",1030,320);
            g.drawString("将处于存在与不",1030,350);
            g.drawString("存在的叠加态，",1030,380);
            g.drawString("被击中时有50%",1030,410);
            g.drawString("概率不掉血",1030,440);
            g.drawString("坦克血量提升" ,1260,330);
            g.drawString("子弹连发加一" ,1480,330);
        }
        for (int i = 4;i < 100;i++){
            if (level == i){
                //实现随机强化
                if (rand == 0){
                    g.drawString("子弹体积提升",1040,330);
                }
                if (rand == 1){
                    g.drawString("子弹连发加一" ,1040,330);
                }
                g.drawString("子弹速度提升" ,1480,330);
                g.drawString("坦克速度提升" ,1260,330);
            }
        }
    }


    //画坦克
    public void drawTank(int x ,int y, Graphics g , int direct, int type){

        switch (type){
            //我方坦克
            case 0 :
                g.setColor(Color.cyan);
                break;
                //敌方坦克
            case 1 :
                g.setColor(Color.yellow);
                break;
        }

        switch (direct){
            //向上
            case 0 :
                g.fill3DRect(x, y,10,60,false);//左轮
                g.fill3DRect(x+30, y,10,60,false);//右轮
                g.fill3DRect(x+10, y +10,20,40,false);//方盖
                g.fillOval(x + 10 ,y + 20 ,20,20);//圆盖
                g.drawLine(x + 20,y + 30,x + 20,y);//炮筒
                break;
            //向右
            case 1 :
                g.fill3DRect(x, y,60,10,false);//左轮
                g.fill3DRect(x, y+30,60,10,false);//右轮
                g.fill3DRect(x+10, y +10,40,20,false);//方盖
                g.fillOval(x + 20 ,y + 10 ,20,20);//圆盖
                g.drawLine(x + 30,y + 20,x + 60,y + 20);//炮筒
                break;
            //向下
            case 2 :
                g.fill3DRect(x, y,10,60,false);//左轮
                g.fill3DRect(x+30, y,10,60,false);//右轮
                g.fill3DRect(x+10, y +10,20,40,false);//方盖
                g.fillOval(x + 10 ,y + 20 ,20,20);//圆盖
                g.drawLine(x + 20,y + 30,x + 20,y + 60);//炮筒
                break;
            //向左
            case 3 :
                g.fill3DRect(x, y,60,10,false);//左轮
                g.fill3DRect(x, y+30,60,10,false);//右轮
                g.fill3DRect(x+10, y +10,40,20,false);//方盖
                g.fillOval(x + 20 ,y + 10 ,20,20);//圆盖
                g.drawLine(x + 30,y + 20,x ,y + 20);//炮筒
                break;
        }
    }


    //子弹击打墙
    public void hitWall() {

        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            for (int j = 0; j < enemyTank.shots.size(); j++) {
                Shot shot = enemyTank.shots.get(j);
                for (int k = 0; k < walls.size(); k++) {
                    Wall wall = walls.get(k);
                    if (shot.x >= wall.x && shot.x <= (wall.x + 20)
                            && shot.y >= wall.y && shot.y <= (wall.y + 20) && wall.wallType == wall.ORDINARY_WALL) {
                        shot.isLive = false;
                        wall.isLive = false;
                        walls.remove(wall);
                    }
                }
            }

        }

        for (int j = 0;j < myTank.shots.size();j++){
            Shot shot = myTank.shots.get(j);
            if (shot != null && shot.isLive) {
                for (int i = 0; i < walls.size(); i++) {
                    Wall wall = walls.get(i);
                    if (shot.x >= wall.x && shot.x <= (wall.x + 20)
                            && (shot.y - (10 * (shotSize - 1))) >= wall.y && (shot.y - (10 * (shotSize - 1))) <= (wall.y + 20)
                            && wall.wallType == wall.ORDINARY_WALL) {
                        shot.isLive = false;
                        myTank.shots.remove(shot);
                        wall.isLive = false;
                        walls.remove(wall);
                    }
                }
            }
        }
    }


    //子弹击打唐小天
    public void hitTang() {
        //如果有顽强的唐小天则无以下判定
        if (tang == 1){
            return;
        }

        for (int i = 0; i < enemyTanks.size(); i++) {
            EnemyTank enemyTank = enemyTanks.get(i);
            for (int j = 0; j < enemyTank.shots.size(); j++) {
                Shot shot = enemyTank.shots.get(j);

                if (shot.x >= 470 && shot.x <= 530
                        && shot.y >= 690 && shot.y <= 750) {
                    shot.isLive = false;
                    System.out.println("---------------你输了-----------------------");
                    System.exit(0);
                }
            }
        }

        for (int j = 0; j < myTank.shots.size(); j++) {
            Shot shot = myTank.shots.get(j);
            if (shot != null && shot.isLive) {
                if (shot.x >= 470 && shot.x <= 530
                        && shot.y >= 690 && shot.y <= 750) {
                    shot.isLive = false;
                    System.out.println("---------------你输了-----------------------");
                    System.exit(0);
                }
            }
        }

    }

    //子弹击打我方坦克
    //遍历敌方每辆坦克的每颗子弹，如果我方坦克存活且敌方子弹还存在，就进入hitTank方法进一步判断是否击中
    public void hitMyTank(){
        for (int i = 0; i < enemyTanks.size();i++){
            EnemyTank enemyTank =  enemyTanks.get(i);
            for (int j = 0 ;j < enemyTank.shots.size(); j++){
                Shot shot = enemyTank.shots.get(j);
                if (myTank.isLive && shot.isLive){
                    hitTank(shot,myTank);
                }
            }

        }
    }

    //子弹击打敌方坦克
    //遍历我方每辆坦克的每颗子弹，如果我方坦克子弹还存在，就进入hitTank方法进一步判断是否击中
    public void hitEnemyTank() {
        for (int j = 0; j < myTank.shots.size(); j++) {
            Shot shot = myTank.shots.get(j);
            if (shot != null && shot.isLive) {
                for (int i = 0; i < enemyTanks.size(); i++) {
                    EnemyTank enemyTank = enemyTanks.get(i);
                    hitTank(shot, enemyTank);
                }
            }
        }
    }


    //判断是否击中
    public void hitTank(Shot s, Tank tank) {
        switch (tank.getDirect()) {
            case 0:
            case 2:
                if (tank instanceof EnemyTank) {
                    if (s.x > tank.getX() && s.x < tank.getX() + 40
                            && (s.y - (10 * (shotSize - 1))) > tank.getY() &&
                            (s.y - (10 * (shotSize - 1))) < tank.getY() + 60) {
                        //如果击中，子弹线程结束，坦克线程也结束
                        s.isLive = false;
                        myTank.shots.remove(s);
                        Record.add();
                        tank.isLive = false;
                        enemyTanks.remove(tank);
                        //经验值加一
                        experience++;
                        //判断是否要升级
                        if (experience == level) {
                            level++;
                            experience = 0;
                        }
                        //初始化boom
                        Bomb bomb = new Bomb(tank.getX(), tank.getY());
                        bombs.add(bomb);
                    }

                }


                //降低我方坦克血量并作血量判断
                if (tank instanceof MyTank) {
                    if (s.x > tank.getX() && s.x < tank.getX() + 40
                            && s.y > tank.getY() && s.y < tank.getY() + 60) {
                        //如果击中，子弹线程结束，坦克线程也结束
                        s.isLive = false;
                        //判断是否有薛定谔的子弹
                        if (xue == 1) {
                            if (((int) (Math.random() * 2)) == 1) {
                                myTank.setLiveNum(myTank.liveNum - 1);
                            }
                        }
                        if (xue == 0) {
                            myTank.setLiveNum(myTank.liveNum - 1);
                        }

                        //如果坦克生命值为零则游戏结束
                        if (myTank.liveNum == 0) {
                            tank.isLive = false;
                            System.out.println("---------------------------坦克生命值归零,游戏结束--------------------------");
                            System.exit(0);
                        }
                        //初始化boom
                        Bomb bomb = new Bomb(tank.getX(), tank.getY());
                        bombs.add(bomb);
                    }
                }


                break;
            case 1:
            case 3:
                if (tank instanceof EnemyTank) {
                    if (s.x > tank.getX() && s.x < tank.getX() + 60
                            && (s.y - (10 * (shotSize - 1))) > tank.getY() &&
                            (s.y - (10 * (shotSize - 1))) < tank.getY() + 40) {
                        //如果击中，子弹线程结束，坦克线程也结束
                        s.isLive = false;
                        myTank.shots.remove(s);
                        Record.add();
                        tank.isLive = false;
                        enemyTanks.remove(tank);
                        experience++;
                        if (experience == level) {
                            level++;
                            experience = 0;
                        }
                        //初始化boom
                        Bomb bomb = new Bomb(tank.getX(), tank.getY());
                        bombs.add(bomb);
                    }

                }


                //降低我方坦克血量并作血量判断
                if (tank instanceof MyTank) {

                    if (s.x > tank.getX() && s.x < tank.getX() + 60
                            && s.y > tank.getY() && s.y < tank.getY() + 40) {
                        //如果击中，子弹线程结束，坦克线程也结束
                        s.isLive = false;
                        if (xue == 1) {
                            if (((int) (Math.random() * 2)) == 1) {
                                myTank.setLiveNum(myTank.liveNum - 1);
                            }
                        }
                        if (xue == 0) {
                            myTank.setLiveNum(myTank.liveNum - 1);
                        }

                        if (myTank.liveNum == 0) {
                            tank.isLive = false;
                            System.out.println("---------------------------坦克生命值归零,游戏结束--------------------------");
                            System.exit(0);
                        }
                        //初始化boom
                        Bomb bomb = new Bomb(tank.getX(), tank.getY());
                        bombs.add(bomb);
                    }
                }
                break;
        }
    }



    //监听键盘输入
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_W){
            myTank.setDirect(0);
            if (myTank.getY() > 0 && !myTank.isOverWall()) {
               myTank.moveUp();
            }
        } else if (e.getKeyCode() == KeyEvent.VK_D){
            myTank.setDirect(1);
            if (myTank.getX() + 60 <1000 && !myTank.isOverWall()) {
                myTank.moveRight();
            }
        }else if (e.getKeyCode() == KeyEvent.VK_S){
            myTank.setDirect(2);
            if (myTank.getY() + 60 < 740 && !myTank.isOverWall()) {
                myTank.moveDown();
            }
        }else if (e.getKeyCode() == KeyEvent.VK_A){
            myTank.setDirect(3);
            if (myTank.getX() > 0 && !myTank.isOverWall()){
                myTank.moveLeft();
            }
        }

        if (e.getKeyCode() == KeyEvent.VK_J) {
            myTank.shotEnemyTank((2 * shotSpeed), shotNum);
        }
        this.repaint();
    }

    //鼠标按下
    @Override
    public void mousePressed(MouseEvent e) {
        //先获得鼠标敲击位置的坐标
        int x = e.getX();
        int y = e.getY();
        //当等级和强化次数对得上才有效
        if ((myTank.liveNum - 2 + shotSpeed - 1 + shotSize - 1 +
                shotNum - 1 + tankSpeed - 1 + tang + xue) != (level - 1)) {
            if (y >= 250 && y <= 450) {

                //下面是各项强化的具体实现
                if (x >= 1020 && x <= 1220) {
                    if (level == 2) {
                        tang = 1;
                        setWall();
                    }
                    if (level == 3) {
                        xue = 1;
                    }
                    if (level > 3) {
                        if (rand == 0) {
                            shotSize++;
                        }
                        if (rand == 1) {
                            shotNum++;
                        }
                    }
                }


                if (x >= 1240 && x <= 1440) {
                    if (level == 2) {
                        shotSpeed++;
                    }
                    if (level == 3) {
                        myTank.setLiveNum(myTank.liveNum++);
                    }
                    if (level > 3) {
                        tankSpeed++;
                    }
                }


                if (x >= 1460 && x <= 1660) {
                    if (level == 2) {
                        shotSize++;
                    }
                    if (level == 3) {
                        shotNum++;
                    }
                    if (level > 3) {
                        shotSpeed++;
                    }
                }


            }
        }
    }



    @Override
    public void run() {
        //实现增加坦克线程
        new Thread(new CreateEnemyTank(enemyTanks,walls)).start();

        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //每隔0.1秒执行子弹击打的各项判断并重绘画面
            //判断是否击中敌方坦克
            hitEnemyTank();
            hitMyTank();
            hitWall();
            hitTang();
            this.repaint();
        }
    }



    //未实现的方法
    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }
    @Override

    public void keyTyped(KeyEvent e) {

    }
    @Override

    public void keyReleased(KeyEvent e) {

    }

}
